package com.nfw.demo.controller.admin;

import com.nfw.demo.dao.UsersMapper;
import com.nfw.demo.entity.Users;
import com.nfw.demo.service.EmailService;
import com.nfw.demo.service.UserService;
import com.nfw.demo.util.UUIDUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;


//@RestController
@Controller
public class UserController{

    private static  Logger logger = Logger.getLogger(UserController.class);

    @Value("${com.mailUrl}")
    private String sendUrl;

    @Autowired
    private UserService userService;

    @Autowired
    private EmailService emailService;
    @Autowired
    private  HttpSession httpSession;

    @Value("${spring.mail.username}")
    private String Sender;

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private UsersMapper usersMapper;


    /**
     * 403无权限页面
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value="/403")
    public String toError(Model model, HttpServletRequest request) {
        return "403";
    }


    @RequestMapping(value = {"/","index","/index"},method = {RequestMethod.POST,RequestMethod.GET})
    public String index(){
        return "user/index";
    }


    /**
     * 登录跳转
     *
     * @param model
     * @return
     */
    @GetMapping({"/login","login.html"})
    public  String toLogin(Model model) {
        return "user/login";
    }

    /**
     * 登录Traditional
     *
     * @param
     * @param model
     * @param
     * @return
     */
    /*
    @PostMapping({"/login","login.html"})
    public String loginPost(Users users,Model model){
        Users users1 = userService.login(users);
        System.out.println(users.getUserName()+ users.getUserPassword());
       // System.out.println(users1.getUserId()+ users1.getUserPassword());
        if(users1!=null) {
            httpSession.setAttribute("user", users1);
            Users name = (Users) httpSession.getAttribute("user"); //放到session中
            return "redirect:/index";

        }else{
            model.addAttribute("error","密码或用户名错误，请重新登录！");
            ///////
            return "login";
        }
    }*/
    @PostMapping({"/login","login.html"})
    public String checklogin(Users users,Model model) {
        String username = users.getUserName();
        logger.info("用户paswd为:"+users.getUserPassword());
        UsernamePasswordToken token = new UsernamePasswordToken(username, users.getUserPassword());
        //获取当前的Subject
        Subject currentUser = SecurityUtils.getSubject();
        try {
            //在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查
            //每个Realm都能在必要时对提交的AuthenticationTokens作出反应
            //所以这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法
            logger.info("对用户[" + username + "]进行登录验证..验证开始");
            currentUser.login(token);
            logger.info("对用户[" + username + "]进行登录验证..验证通过");
        }catch(UnknownAccountException uae){
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,未知账户or state=0");
            model.addAttribute("error", "无此账户/未激活");
        }catch(IncorrectCredentialsException ice){
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误的凭证");
            model.addAttribute("error", "密码不正确");
        }catch(LockedAccountException lae){
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,账户已锁定");
            model.addAttribute("error", "账户已锁定");
        }catch(ExcessiveAttemptsException eae){
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误次数过多");
            model.addAttribute("error", "用户名或密码错误次数过多");
        }catch(AuthenticationException ae){
            //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,堆栈轨迹如下");
            model.addAttribute("error", "用户名或密码不正确");
            ae.printStackTrace();
        }
        //验证是否登录成功
        if(currentUser.isAuthenticated()){
            logger.info("用户[" + username + "]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)");
            Date date = new Date();
            users.setUserLudt(date);
            usersMapper.basicUpdate(users);
            return "redirect:/index";
        }else{
            token.clear();
           return "user/login";
        }


    }

    @GetMapping({"register","register.html"})
    public String toRegister(Model model){ return "user/register";}

    @PostMapping({"register","register.html"})
    public String registerPost(Users users,Model model){
        logger.info("-----注册------");
        logger.info("用户名：" + users.getUserName());
        logger.info("email：" + users.getUserEmail());


        try {
            userService.selectIsName(users);
            logger.info("是否存在此账户or邮箱:"+userService.selectIsName(users));
            model.addAttribute("error", "该账号或邮箱已存在！");
        } catch (Exception e) {

            //生成随机6位数ID ，并用findid来检验是否重复
            int rand=0;
            boolean repeat = false;
            while (repeat == false) {
                rand = (int) ((Math.random() * 9 + 1) * 100000);
                users.setUserId(String.valueOf(rand));
                try{
                userService.findId(users);
                } catch (Exception r){
                    repeat = true;
                }
            }
            logger.info("Id 的值为:" + users.getUserId());



            //md5 盐加密密码
            String hashAlgorithmName = "MD5";//加密方式
            Object crdentials = users.getUserPassword();//密码原值
            ByteSource salt = ByteSource.Util.bytes(users.getUserName());//以账号作为盐值
            int hashIterations = 1024;//加密1024次
            Object result = new SimpleHash(hashAlgorithmName,crdentials,salt,hashIterations);

            users.setUserPassword(result.toString());
            logger.info("加密后的密码为:"+result.toString());
            users.setActiState(0);
            String code = UUIDUtils.getUUID()+ UUIDUtils.getUUID();
            users.setActiCode(code);
            Date date = new Date();
            users.setUserAdddate(date);
            users.setUserLudt(date);
            userService.register(users);
            model.addAttribute("error", "请到您指定的邮箱完成激活！");
            return "user/login";
        }

        return "user/register";
    }

    @RequestMapping(value = "/checkCode")
    public String checkCode(String code){
        Users users = userService.checkCode(code);
        logger.info("旧的users Name:"+users.getUserName()+"\n"+"旧的useracticode:"+users.getActiCode());
        //如果用户不等于null，把用户状态修改status=1
        if (users !=null){
                users.setActiState(1);
                //把code验证码清空，已经不需要了
                users.setActiCode("");
                logger.info("新的users Name:" + users.getUserName() + "\n" + "新的useracticode:" + users.getActiCode());
                userService.updateUserState(users);
        }

        return "user/login";
    }

    @RequestMapping(value = "/pswdCheck")
    public String pswdCheck(String code)
    {
        Users users = userService.checkCode(code);
        if (users !=null){
            return "redirect:/updatePswd?code="+code;
        }
        else {
            return "user/login";

        }
    }

    @RequestMapping(value = "/updatePswd")
    public String updatePswd(String code)
    {
        logger.info("code 为:"+code);
        Session session = SecurityUtils.getSubject().getSession();
        session.setAttribute("code", code); //把code存入session
        return "user/updatePswd";
    }

    @PostMapping({"updatePswd","updatePswd.html"})
    public String postUpdatePswd(Users userst,Model model) {
        Session session = SecurityUtils.getSubject().getSession();
        String tcode = session.getAttribute("code").toString();
        logger.info("密码为:"+userst.getUserPassword());

        logger.info("tcode为:" + tcode);
        Users users = userService.checkCode(tcode);
        users.setUserPassword(userst.getUserPassword());
        logger.info("username为:" + users.getUserName());

        if (users != null) {
            logger.info("password为"+users.getUserPassword());
            //md5 盐加密密码
            String hashAlgorithmName = "MD5";
            Object crdentials = users.getUserPassword();
            ByteSource salt = ByteSource.Util.bytes(users.getUserName());
            int hashIterations = 1024;
            Object result = new SimpleHash(hashAlgorithmName, crdentials, salt, hashIterations);
            users.setUserPassword(result.toString());
            logger.info("md5密码为:" + result.toString());

            users.setActiCode("");
            userService.updatePassword(users);
            //  model.addAttribute("error","修改成功，点击跳转登录界面");
            model.addAttribute("error", "修改成功！");
            return "user/login";
        } else {
            return "user/updatePswd";
        }
    }

    @GetMapping({"/forget","forget"})
    public String forgetGet(Model model) {
        return "user/forget";
    }


    @PostMapping({"/forget","forget"})
    public String forgetPost(Users users, Model model) {
        logger.info(users.getUserName()+ users.getUserEmail());
        String password = userService.selectPasswordByName(users);
        logger.info(users.getUserName()+ users.getUserEmail());

        if (password == null) {
            model.addAttribute("error", "帐号不存在或邮箱不正确！");
        } else {

            String code = UUIDUtils.getUUID()+ UUIDUtils.getUUID();
            users.setActiCode(code);
            usersMapper.upAntiCode(users);
            logger.info("ActiCode:"+code);
            //主题
            String subject = "来自kiwi的修改密码邮件";
            StringBuffer context = new StringBuffer();
            context.append("<h1>你好哇:"+users.getUserName()+"</h1>")
                    .append("<h1>修改密码请点击：</h1><br/><h3><a href='"+sendUrl+"pswdCheck?code="+code+"'>Click Me</a></h3>");
            //发送激活邮件
            emailService.sendEmail(users.getUserEmail(),subject,context);
            model.addAttribute("error", "请到您的邮箱点击链接修改,请查收！");
        }
        return "user/forget";
    }

    /**
     * 用户退出
     *
     * @return 跳转到登录页面
     */
    @RequestMapping("/logout")
    public String logout() {
        //使用权限管理工具进行用户的退出，跳出登录，给出提示信息
        SecurityUtils.getSubject().logout();
        return "redirect:/index";
    }


}
